#!/bin/sh
patch -p0 < $0
exit 0
Index: compiler-orig/include/llvm/Target/TargetSubtargetInfo.h
===================================================================
--- compiler/include/llvm/Target/TargetSubtargetInfo.h	(LLVM 3.5)
+++ compiler/include/llvm/Target/TargetSubtargetInfo.h	(clang-omp)
@@ -126,6 +126,10 @@
   /// \brief Reset the features for the subtarget.
   virtual void resetSubtargetFeatures(const MachineFunction *MF) { }
 
+  /// \brief Controls whether linkage and alignments are supposed to be printed
+  /// for functions by the Asm Printer
+  virtual bool allowAsmPrintForFunctionAlignAndLinkage() const {return true;}
+
 };
 
 } // End llvm namespace
Index: compiler/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- compiler/lib/CodeGen/AsmPrinter/AsmPrinter.cpp	(LLVM 3.5)
+++ compiler/lib/CodeGen/AsmPrinter/AsmPrinter.cpp	(clang-omp)
@@ -516,8 +516,11 @@
       getObjFileLowering().SectionForGlobal(F, *Mang, TM));
   EmitVisibility(CurrentFnSym, F->getVisibility());
 
-  EmitLinkage(F, CurrentFnSym);
-  EmitAlignment(MF->getAlignment(), F);
+  if (TM.getSubtarget<TargetSubtargetInfo>()
+      .allowAsmPrintForFunctionAlignAndLinkage()){
+    EmitLinkage(F, CurrentFnSym);
+    EmitAlignment(MF->getAlignment(), F);
+  }
 
   if (MAI->hasDotTypeDotSizeDirective())
     OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
Index: compiler/lib/IR/Value.cpp
===================================================================
--- compiler/lib/IR/Value.cpp	(LLVM 3.5)
+++ compiler/lib/IR/Value.cpp	(clang-omp)
@@ -341,8 +341,14 @@
   assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
   assert(!contains(New, this) &&
          "this->replaceAllUsesWith(expr(this)) is NOT valid!");
-  assert(New->getType() == getType() &&
+  // We are allowing replaces are valid for pointers of different address spaces
+  assert((getType()->isPointerTy() || New->getType() == getType()) &&
          "replaceAllUses of value with new value of different type!");
+  assert((!getType()->isPointerTy()
+      || cast<PointerType>(New->getType())->getPointerElementType()
+         == cast<PointerType>(getType())->getPointerElementType())
+      && "replaceAllUses of pointer value with new value of different element "
+         "type!");
 
   // Notify all ValueHandles (if present) that this value is going away.
   if (HasValueHandle)
Index: compiler/lib/Support/Triple.cpp
===================================================================
--- compiler/lib/Support/Triple.cpp	(LLVM 3.5)
+++ compiler/lib/Support/Triple.cpp	(clang-omp)
@@ -280,7 +280,11 @@
     .Case("tce", Triple::tce)
     .Case("xcore", Triple::xcore)
     .Case("nvptx", Triple::nvptx)
+    // FIXME: It would be good to replace these with explicit names for all the
+    // various suffixes supported.
+    .StartsWith("nvptxsm_", Triple::nvptx)
     .Case("nvptx64", Triple::nvptx64)
+    .StartsWith("nvptx64sm_", Triple::nvptx64)
     .Case("le32", Triple::le32)
     .Case("amdil", Triple::amdil)
     .Case("spir", Triple::spir)
Index: compiler/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
===================================================================
--- compiler/lib/Target/NVPTX/NVPTXAsmPrinter.cpp	(LLVM 3.5)
+++ compiler/lib/Target/NVPTX/NVPTXAsmPrinter.cpp	(clang-omp)
@@ -1908,6 +1908,31 @@
   llvm_unreachable("Not scalar type found in printScalarConstant()");
 }
 
+// These utility functions assure we get the right sequence of bytes for a given
+// type even for big-endian machines
+template<typename T>
+static void ConvertIntToBytes(unsigned char *p, T val){
+  int64_t vp = (int64_t)val;
+  for (unsigned i=0; i<sizeof(T); ++i){
+    p[i] = (unsigned char)vp;
+    vp >>= 8;
+  }
+}
+static void ConvertFloatToBytes(unsigned char *p, float val){
+  int32_t *vp = (int32_t*)&val;
+  for (unsigned i=0; i<sizeof(int32_t); ++i){
+    p[i] = (unsigned char)*vp;
+    *vp >>= 8;
+  }
+}
+static void ConvertDoubleToBytes(unsigned char *p, double val){
+  int64_t *vp = (int64_t*)&val;
+  for (unsigned i=0; i<sizeof(int64_t); ++i){
+    p[i] = (unsigned char)*vp;
+    *vp >>= 8;
+  }
+}
+
 void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
                                    AggBuffer *aggBuffer) {
 
@@ -1921,7 +1946,7 @@
     return;
   }
 
-  unsigned char *ptr;
+  unsigned char ptr[8];
   switch (CPV->getType()->getTypeID()) {
 
   case Type::IntegerTyID: {
@@ -1929,23 +1954,23 @@
     if (ETy == Type::getInt8Ty(CPV->getContext())) {
       unsigned char c =
           (unsigned char)(dyn_cast<ConstantInt>(CPV))->getZExtValue();
-      ptr = &c;
+      ConvertIntToBytes<>(ptr,c);
       aggBuffer->addBytes(ptr, 1, Bytes);
     } else if (ETy == Type::getInt16Ty(CPV->getContext())) {
       short int16 = (short)(dyn_cast<ConstantInt>(CPV))->getZExtValue();
-      ptr = (unsigned char *)&int16;
+      ConvertIntToBytes<>(ptr,int16);
       aggBuffer->addBytes(ptr, 2, Bytes);
     } else if (ETy == Type::getInt32Ty(CPV->getContext())) {
       if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
         int int32 = (int)(constInt->getZExtValue());
-        ptr = (unsigned char *)&int32;
+        ConvertIntToBytes<>(ptr,int32);
         aggBuffer->addBytes(ptr, 4, Bytes);
         break;
       } else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
         if (const ConstantInt *constInt = dyn_cast<ConstantInt>(
                 ConstantFoldConstantExpression(Cexpr, TD))) {
           int int32 = (int)(constInt->getZExtValue());
-          ptr = (unsigned char *)&int32;
+          ConvertIntToBytes<>(ptr,int32);
           aggBuffer->addBytes(ptr, 4, Bytes);
           break;
         }
@@ -1960,14 +1985,14 @@
     } else if (ETy == Type::getInt64Ty(CPV->getContext())) {
       if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
         long long int64 = (long long)(constInt->getZExtValue());
-        ptr = (unsigned char *)&int64;
+        ConvertIntToBytes<>(ptr,int64);
         aggBuffer->addBytes(ptr, 8, Bytes);
         break;
       } else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
         if (const ConstantInt *constInt = dyn_cast<ConstantInt>(
                 ConstantFoldConstantExpression(Cexpr, TD))) {
           long long int64 = (long long)(constInt->getZExtValue());
-          ptr = (unsigned char *)&int64;
+          ConvertIntToBytes<>(ptr,int64);
           aggBuffer->addBytes(ptr, 8, Bytes);
           break;
         }
@@ -1989,11 +2014,11 @@
     const Type *Ty = CFP->getType();
     if (Ty == Type::getFloatTy(CPV->getContext())) {
       float float32 = (float) CFP->getValueAPF().convertToFloat();
-      ptr = (unsigned char *)&float32;
+      ConvertFloatToBytes(ptr,float32);
       aggBuffer->addBytes(ptr, 4, Bytes);
     } else if (Ty == Type::getDoubleTy(CPV->getContext())) {
       double float64 = CFP->getValueAPF().convertToDouble();
-      ptr = (unsigned char *)&float64;
+      ConvertDoubleToBytes(ptr,float64);
       aggBuffer->addBytes(ptr, 8, Bytes);
     } else {
       llvm_unreachable("unsupported fp const type");
Index: compiler/lib/Target/NVPTX/NVPTXISelLowering.cpp
===================================================================
--- compiler/lib/Target/NVPTX/NVPTXISelLowering.cpp	(LLVM 3.5)
+++ compiler/lib/Target/NVPTX/NVPTXISelLowering.cpp	(clang-omp)
@@ -867,9 +867,20 @@
 SDValue
 NVPTXTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
   SDLoc dl(Op);
-  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+
+  GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
+
+  const GlobalValue *GV = GN->getGlobal();
   Op = DAG.getTargetGlobalAddress(GV, dl, getPointerTy());
-  return DAG.getNode(NVPTXISD::Wrapper, dl, getPointerTy(), Op);
+  Op = DAG.getNode(NVPTXISD::Wrapper, dl, getPointerTy(), Op);
+
+  // We need to consider any offset that comes with the global
+  if (GN->getOffset()){
+    SDValue Offset = DAG.getConstant(GN->getOffset(),getPointerTy());
+    Op = DAG.getNode(ISD::ADD,Op,getPointerTy(),Op,Offset);
+  }
+
+  return Op;
 }
 
 std::string
Index: compiler/lib/Target/NVPTX/NVPTXSubtarget.h
===================================================================
--- compiler/lib/Target/NVPTX/NVPTXSubtarget.h	(LLVM 3.5)
+++ compiler/lib/Target/NVPTX/NVPTXSubtarget.h	(clang-omp)
@@ -109,6 +109,8 @@
 
   NVPTXSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
+
+  bool allowAsmPrintForFunctionAlignAndLinkage() const {return false;}
 };
 
 } // End llvm namespace
Index: compiler/lib/Target/PowerPC/PPCFastISel.cpp
===================================================================
--- compiler/lib/Target/PowerPC/PPCFastISel.cpp	(LLVM 3.5)
+++ compiler/lib/Target/PowerPC/PPCFastISel.cpp	(clang-omp)
@@ -153,7 +153,7 @@
                            unsigned DestReg, bool IsZExt);
     unsigned PPCMaterializeFP(const ConstantFP *CFP, MVT VT);
     unsigned PPCMaterializeGV(const GlobalValue *GV, MVT VT);
-    unsigned PPCMaterializeInt(const Constant *C, MVT VT);
+    unsigned PPCMaterializeInt(const Constant *C, MVT VT, bool UseSExt = true);
     unsigned PPCMaterialize32BitInt(int64_t Imm,
                                     const TargetRegisterClass *RC);
     unsigned PPCMaterialize64BitInt(int64_t Imm,
@@ -898,10 +898,10 @@
   if (SrcVT == MVT::i32) {
     if (!IsSigned) {
       LoadOpc = PPC::LFIWZX;
-      Addr.Offset = 4;
+      Addr.Offset = (PPCSubTarget->isLittleEndian()) ? 0 : 4;
     } else if (PPCSubTarget->hasLFIWAX()) {
       LoadOpc = PPC::LFIWAX;
-      Addr.Offset = 4;
+      Addr.Offset = (PPCSubTarget->isLittleEndian()) ? 0 : 4;
     }
   }
 
@@ -1548,11 +1548,33 @@
 
     // Special case for returning a constant integer of any size.
     // Materialize the constant as an i64 and copy it to the return
-    // register.  This avoids an unnecessary extend or truncate.
+    // register. We still need to worry about properly extending the sign. E.g:
+    // If the constant has only one bit, it means it is a boolean. Therefore
+    // we can't use PPCMaterializeInt because it extends the sign which will
+    // cause negations of the returned value to be incorrect as they are
+    // implemented as the flip of the least significant bit.
     if (isa<ConstantInt>(*RV)) {
       const Constant *C = cast<Constant>(RV);
-      unsigned SrcReg = PPCMaterializeInt(C, MVT::i64);
-      unsigned RetReg = ValLocs[0].getLocReg();
+
+      CCValAssign &VA = ValLocs[0];
+
+      unsigned RetReg = VA.getLocReg();
+      unsigned SrcReg = 0;
+
+      switch (VA.getLocInfo()) {
+        default:
+          llvm_unreachable("Unknown loc info!");
+          break;
+        case CCValAssign::Full:
+        case CCValAssign::AExt:
+        case CCValAssign::ZExt:
+          SrcReg = PPCMaterializeInt(C, MVT::i64, false);
+          break;
+        case CCValAssign::SExt:
+          SrcReg = PPCMaterializeInt(C, MVT::i64, true);
+          break;
+      }
+
       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
               TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);
       RetRegs.push_back(RetReg);
@@ -2014,7 +2036,8 @@
 
 // Materialize an integer constant into a register, and return
 // the register number (or zero if we failed to handle it).
-unsigned PPCFastISel::PPCMaterializeInt(const Constant *C, MVT VT) {
+unsigned PPCFastISel::PPCMaterializeInt(const Constant *C, MVT VT,
+                                                           bool UseSExt) {
   // If we're using CR bit registers for i1 values, handle that as a special
   // case first.
   if (VT == MVT::i1 && PPCSubTarget->useCRBits()) {
@@ -2038,7 +2061,7 @@
     unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
     unsigned ImmReg = createResultReg(RC);
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg)
-      .addImm(CI->getSExtValue());
+      .addImm( (UseSExt) ? CI->getSExtValue() : CI->getZExtValue() );
     return ImmReg;
   }
 
